from flask import Blueprint, request, jsonify
from global_var import response_dict
import os
import copy
from concurrent.futures import ThreadPoolExecutor


# 全局共享线程池 - 用于异步执行耗时任务
# 最大工作线程数可根据实际需求调整
shared_executor: ThreadPoolExecutor = ThreadPoolExecutor(max_workers=5)

def getResponse(code: int, message: str = "", data = None):
    res = copy.deepcopy(response_dict)
    res["code"] = code
    res["message"] = message
    res["data"] = data
    
    # 业务码到HTTP状态码的映射
    http_code = 200 if code == 200 else 400
    
    return jsonify(res), http_code



# -------------------------- 常量定义（统一管理路径，避免硬编码） --------------------------
# 项目根目录（根据实际结构调整，确保路径正确）
PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../"))
# 暂存目录：保存待编译的.h和.cpp文件
STAGING_DIR = os.path.join(PROJECT_ROOT, "db", "input_atomic_service")
# 最终服务目录：编译成功后生成的服务文件
SERVICE_DIR = os.path.join(PROJECT_ROOT, "db", "atomic_service")
# 客户端目录：保存客户端代码
CLIENT_DIR = os.path.join(PROJECT_ROOT, "db", "client")


# 支持的文件类型（键：后缀，值：类型描述）
SUPPORTED_FILE_TYPES = [
    ".h",  # C头文件
    ".hpp",  # C++头文件
    ".c",  # C源文件
    ".cpp",  # C++源文件
    ".json" # json文件
]



# -------------------------- 工具函数 --------------------------
def extract_service_info(filename: str) -> tuple[str, str]:
    """
    从文件名提取服务名和文件类型
    :return: (service_name, file_type)
    :raise: ValueError 若文件类型不支持或文件名无效
    """
    if not filename:
        raise ValueError("文件名为空")
    
    # 提取后缀（忽略大小写，如.H/.CPP也能识别）
    lower_filename = filename.lower()
    for file_type in SUPPORTED_FILE_TYPES:
        if lower_filename.endswith(file_type):
            # 提取服务名（去除后缀）
            service_name = os.path.splitext(filename)[0].strip()
            # 校验服务名合法性（禁止特殊字符）
            if not service_name or any(c in service_name for c in r'\/:*?"<>|'):
                raise ValueError(f"服务名[{service_name}]包含特殊字符或为空")
            return service_name, file_type
    
    # 不支持的文件类型
    supported_suffixes = ", ".join(SUPPORTED_FILE_TYPES)
    raise ValueError(f"不支持的文件类型，仅支持：{supported_suffixes}（文件：{filename}）")


def get_service_staging_dir(service_name: str) -> str:
    """获取服务的暂存目录路径"""
    return os.path.join(STAGING_DIR, service_name)


# 编译触发条件：必须包含头文件 + 至少一个源文件（.c或.cpp）
def is_compile_ready(service_name: str) -> bool:
    """判断服务是否满足编译条件"""
    service_dir = get_service_staging_dir(service_name)
    if not os.path.exists(service_dir):
        return False
    # 检查是否有头文件
    has_header = os.path.exists(os.path.join(service_dir, f"{service_name}.h"))
    has_headerpp = os.path.exists(os.path.join(service_dir, f"{service_name}.hpp"))
    # 检查是否有至少一个源文件（.c或.cpp）
    has_c_source = os.path.exists(os.path.join(service_dir, f"{service_name}.c"))
    has_cpp_source = os.path.exists(os.path.join(service_dir, f"{service_name}.cpp"))
    return (has_header or has_headerpp) and (has_c_source or has_cpp_source)